//#include<stdio.h>
//#include<unistd.h>
/*int main()
{
  int cnt=0;
  while(1)
  {
    int ret=fork();//创建子进程
    if(ret<0)
    {
      printf("fork error!,cnt:%d\n",cnt);
      break;
    }
    else if(ret==0)//子进程
    {
         while(1) 
         {
           sleep(1);
         }
    }
    else//父进程
    {
      cnt++;
    }
  }
  return 0;
}*/
/*#include<stdio.h>
#include<string.h>
int addToTarget(int from,int to)
{
  int sum=0;
  int i=0;
  for(i=from;i<=to;i++)
  {
    sum += i;
  }
  return sum;
}
int main()
{ 
  //写代码是为了完成某件事情，我如何得知我的任务跑的如何呢？
  //进程退出码
  int num=addToTarget(1,100);
  if(num==5050)
    return 0;
  else
    return 1;
  //如何设定main返回值？？如果不关心退出码，return0就行
  //如果未来我们要关心进程退出码时，要返回特定的数据表明特定错误
  //进程退出的时候，对应的退出码
  //标定进程执行的结果是否正确
//  return 0;
}*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#define NUM 10
typedef void (*func_t)();//函数指针
func_t handleTask[NUM];
//样例任务
void task1()
{
  printf("handle task1\n");
}
void task2()
{
  printf("handle task2\n");
}
void task3()
{
  printf("handle task3\n");
}
void loadTask()
{
  memset(handleTask,0,sizeof(handleTask));
  handleTask[0]=task1;
  handleTask[1]=task2;
  handleTask[2]=task3;
}
int main()
{
  pid_t id=fork();
  if(id==0)
  {
    //子进程
    int cnt=10;
    while(cnt)
    {
       printf("我是子进程: %d,父进程: %d,cnt: %d\n",getpid(),getppid(),cnt--);
       sleep(1);
    }
    exit(0);//进程退出
  }
  //parent
  //测试轮询非阻塞等待
  int status=0;
  while(1)
   { 
     loadTask();
    pid_t ret=waitpid(id,&status,WNOHANG);//WNOHANG:非阻塞->子进程没有退出，父进程检测时，立即返回
    if(ret==0)
    {
      //waitpid调用成功&&子进程没有退出
      //子进程没有退出，我的waitpid没有等待失败，仅仅是检测到了子进程没有退出
      printf("wait done,but child is running..,parent running other things\n");
      for(int i=0;handleTask[i]!=NULL;i++)
      {
        handleTask[i]();//采用回调方式，执行我们想让父进程在空闲时候做的事情
      }

    }
    else if(ret>0)
    {
      //子进程退出
      printf("wait sucess,exit code:%d,sig:%d\n", (status>>8)&0xFF, status & 0x7F);
      break;
    }
    else{
      //waitpid调用失败
      printf("waitpid call failed\n");
      
    }
    sleep(1);
  }
  //父进程
 // pid_t ret=wait(NULL);//回收子进程
//  int status=0;//不是被整体使用的，有自己的位图结构
  //1.让os释放处于僵尸状态的子进程
  //2.获取子进程的退出结果
  //在等待期间，子进程没有退出时，父进程只能阻塞等待
// pid_t ret=waitpid(id,&status,0);
 // if(id>0)
//  {
//    if(ret>0)
//    {
      //判断是否正常退出
  //    if(WIFEXITED(status))
  //    {
        //判断子进程运行结果是否ok
     //   printf("exit code:%d\n",WEXITSTATUS(status));//若WEXITSTATUS非零，提取子进程退出码
   //   }
//      else{
//        printf("没有正常退出");
//      }
//    }

   // printf("wait success:%d,sig number:%d,child exit code:%d\n",ret,(status&0x7F),(status>>8)&0xFF);
//  }
//  sleep(5);
  return 0;
 
}































